package com.logica.mdm.webservices;

import java.util.List;

import javax.jws.WebService;

import org.apache.cxf.binding.soap.SoapFault;
import org.apache.cxf.interceptor.Fault;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.TargetSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import com.logica.mdm.webservices.dao.CrmAccountDao;
import com.logica.mdm.webservices.dao.CrmContactDao;
import com.logica.mdm.webservices.dao.impl.SiperianClientCrmAccountDao;
import com.logica.mdm.webservices.dao.impl.SiperianClientCrmContactDao;
import com.logica.mdm.webservices.dataobject.mdm.CleansePutTypedResponse;
import com.logica.mdm.webservices.messages.CleansePutCrmAccountCompositeRequest;
import com.logica.mdm.webservices.messages.CleansePutCrmAccountCompositeResponse;
import com.logica.mdm.webservices.messages.CleansePutCrmContactCompositeRequest;
import com.logica.mdm.webservices.messages.CleansePutCrmContactCompositeResponse;
import com.logica.mdm.webservices.utils.SiperianPoolUtils;
import com.logica.mdm.webservices.utils.SiperianRunnable;

/**
 * Composite MDM Web Service for Nexity (implementation).
 * @author Fabien Crespel <fabien.crespel@logica.com>
 */
@WebService(serviceName="NexityCompositeService", portName="NexityCompositeServicePort",
	endpointInterface="com.logica.mdm.webservices.NexityCompositeService")
public class NexityCompositeServiceImpl extends SpringBeanAutowiringSupport implements NexityCompositeService {
	
	private static final Logger logger = LoggerFactory.getLogger(NexityCompositeServiceImpl.class);
	
	@Autowired
	@Qualifier("siperianClientPool")
	protected TargetSource siperianClientPool;

	@Override
	public CleansePutCrmContactCompositeResponse cleansePutCrmContact(final CleansePutCrmContactCompositeRequest crmContactCompositeRequest) {
		// Init the composite response
		final CleansePutCrmContactCompositeResponse crmContactCompositeResponse = new CleansePutCrmContactCompositeResponse();
		crmContactCompositeResponse.setInteractionId(crmContactCompositeRequest.getInteractionId());
		
		try {
			SiperianPoolUtils.executeRunnableTransacted(siperianClientPool, new SiperianRunnable() {
				@Override
				public void doRun() throws Exception {
					// Cleanse & Put the CRM Contact object
					CrmContactDao crmContactDao = new SiperianClientCrmContactDao(getSiperianClient());
					List<CleansePutTypedResponse> responses = crmContactDao.cleansePutCrmContact(crmContactCompositeRequest);
					
					// Finish filling the composite response
					crmContactCompositeResponse.setCleansePutResponse(responses);
					crmContactCompositeResponse.setMessage("The composite CLEANSE PUT was processed successfully");
				}
			});
			
		} catch (Throwable e) {
			logger.error("Service cleansePutCrmContact failed.", e);
			throw new SoapFault("Service cleansePutCrmContact failed. " + e.toString(), e, Fault.FAULT_CODE_SERVER);
		}
		
		return crmContactCompositeResponse;
	}

	@Override
	public CleansePutCrmAccountCompositeResponse cleansePutCrmAccount(final CleansePutCrmAccountCompositeRequest crmAccountCompositeRequest) {
		// Init the composite response
		final CleansePutCrmAccountCompositeResponse crmAccountCompositeResponse = new CleansePutCrmAccountCompositeResponse();
		crmAccountCompositeResponse.setInteractionId(crmAccountCompositeRequest.getInteractionId());

		try {
			SiperianPoolUtils.executeRunnableTransacted(siperianClientPool, new SiperianRunnable() {
				@Override
				public void doRun() throws Exception {
					// Cleanse & Put the CRM Account object
					CrmAccountDao crmAccountDao = new SiperianClientCrmAccountDao(getSiperianClient());
					List<CleansePutTypedResponse> responses = crmAccountDao.cleansePutCrmAccount(crmAccountCompositeRequest);

					// Finish filling the composite response
					crmAccountCompositeResponse.setCleansePutResponse(responses);
					crmAccountCompositeResponse.setMessage("The composite CLEANSE PUT was processed successfully");
				}
			});
			
		} catch (Throwable e) {
			logger.error("Service cleansePutCrmAccount failed.", e);
			throw new SoapFault("Service cleansePutCrmAccount failed. " + e.toString(), e, Fault.FAULT_CODE_SERVER);
		}
		
		return crmAccountCompositeResponse;
	}

}
